package com.relytosoft.mizar.media.alarm.services.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.relytosoft.dubhe.common.core.base.page.PageQuery;
import com.relytosoft.mizar.media.alarm.api.entity.Alarm;
import com.relytosoft.mizar.media.alarm.api.pojo.dto.AyControlAlarmDto;
import com.relytosoft.mizar.media.alarm.api.pojo.query.AlarmQuery;
import com.relytosoft.mizar.media.alarm.api.pojo.vo.*;
import com.relytosoft.mizar.media.alarm.services.mapper.AlarmMapper;
import com.relytosoft.mizar.media.alarm.services.service.AlarmService;
import com.relytosoft.mizar.media.common.constant.AlarmTypeConstants;
import com.relytosoft.mizar.media.common.constant.ControlConstants;
import com.relytosoft.mizar.media.common.constant.MediaMqConstants;
import com.relytosoft.mizar.media.common.emqx.client.MqttOp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.*;

/**
 * @author wss
 * @version 1.0
 * @date 2022/5/24 11:54
 */
@Service
public class AlarmServiceImpl extends ServiceImpl<AlarmMapper, Alarm> implements AlarmService {

    static ThreadPoolExecutor threadPoolExecutor;

    static {
        threadPoolExecutor = new ThreadPoolExecutor(
                (int) (Runtime.getRuntime().availableProcessors() * 1.5),
                Runtime.getRuntime().availableProcessors() * 3,
                60L,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<Runnable>(10000),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
        );
    }

    protected Logger log = LoggerFactory.getLogger(this.getClass());

    @Override
    public Boolean alarmAccept(AyControlAlarmDto ayControlAlarmDto) {
        try {
            Alarm alarm = AyControlAlarmDto.buildAlarm(ayControlAlarmDto);
            CompletableFuture<Void> saveFuture = CompletableFuture.runAsync(() -> this.save(alarm), threadPoolExecutor);
            CompletableFuture<Void> recordFuture = CompletableFuture.runAsync(() -> MqttOp.publish(MediaMqConstants.ALARM_TOPIC, JSON.toJSONString(alarm)));
            CompletableFuture.allOf(saveFuture, recordFuture).get();
            return true;
        } catch (Exception e) {
            log.info("接受上报预警异常--{}", ayControlAlarmDto, e);
            return false;
        }
    }

    @Override
    public IPage<AlarmListVo> selectPageAlarmList(PageQuery pageQuery, AlarmQuery alarmQuery) {
        if (StrUtil.isBlank(pageQuery.getOrderByColumn())) {
            pageQuery.setOrderByColumn("id");
            pageQuery.setIsAsc("desc");
        }
        return baseMapper.selectPageAlarmList(pageQuery.build(), alarmQuery);
    }

    @Override
    public List<TaskSelectVo> selectControlTaskList(Integer dispositionType) {
        return baseMapper.selectControlTaskList(dispositionType);
    }

    @Override
    public AlarmVo selectAlarmDetail(Long id) {
        AlarmVo alarmVo = baseMapper.selectAlarmDetailById(id);
        AlarmTaskTypeVo alarmTaskTypeVo = baseMapper.selectTaskTypeByControlId(alarmVo.getTaskId());
        if (alarmVo.getAlarmTypeId() == AlarmTypeConstants.CONDITION_ALARM_CONTROL) {
            if (alarmTaskTypeVo.getDispositionCategory() == ControlConstants.STRUCTURE_DISPOSITION_CATEGORY_PEOPLE) {
                alarmVo.setAlarmTypeName("行人条件布控");
            }
            if (alarmTaskTypeVo.getDispositionCategory() == ControlConstants.STRUCTURE_DISPOSITION_CATEGORY_VEHICLE) {
                alarmVo.setAlarmTypeName("车辆条件布控");
            }
            if (alarmTaskTypeVo.getDispositionCategory() == ControlConstants.STRUCTURE_DISPOSITION_CATEGORY_NON_VEHICLE) {
                alarmVo.setAlarmTypeName("非车辆条件布控");
            }
        } else if (alarmVo.getAlarmTypeId() == AlarmTypeConstants.IMAGE_ALARM_CONTROL) {
            if (alarmTaskTypeVo.getDispositionCategory() == ControlConstants.STRUCTURE_DISPOSITION_CATEGORY_PEOPLE) {
                alarmVo.setAlarmTypeName("行人图像布控");
            }
            if (alarmTaskTypeVo.getDispositionCategory() == ControlConstants.STRUCTURE_DISPOSITION_CATEGORY_VEHICLE) {
                alarmVo.setAlarmTypeName("车辆图像布控");
            }
            if (alarmTaskTypeVo.getDispositionCategory() == ControlConstants.STRUCTURE_DISPOSITION_CATEGORY_NON_VEHICLE) {
                alarmVo.setAlarmTypeName("非车辆图像布控");
            }
        }
        return alarmVo;
    }

    @Override
    public List<AlarmTypeVo> selectAlarmTypeList(Integer alarmCategory) {
        return baseMapper.selectAlarmTypeList(alarmCategory);
    }

}
